home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-07-15 | 3.0 KB | 108 lines | [TEXT/MACA] |
-
- Bob,
-
- I have been reviewing your question on how to set the contents of STR# resources
- from your program.
-
- As it turns out, there is no Toolbox call to do this, mostly because resources are
- not meant to store data which changes frequently. I have a solution to your
- problem, but it comes with a warning: PLEASE DON'T CHANGE ANY OF YOUR APPLICATIONS
- RESOURCES WHILE RUNNING. Doing so will make it impossible for your program to run
- off of a fileserver or locked volume.
-
- That out of the way the format of an STR# resource is:
-
- 2 bytes number of strings
- -------------------------------
- 1 byte length of 1st str
- (variable) 1st string data
- -------------------------------
- 1 byte length of nth str
- (variable) nth string data
- ...
- ...
-
- Note that the indexes into the strings are not at set positions, but instead are
- relative to the lengths of the previous strings.
-
- Finally, here's a C function, SetIndString() which takes the same parameters as
- GetIndString(). This call does the opposite, namely, it sets a particular STR#
- string to the passed in string:
-
- -------------
-
- OSErr SetIndString(StringPtr theStr,short resID,short strIndex)
- {
- Handle theRes; /* handle pointing to STR# resource */
- short numStrings; /* number of strings in STR# */
- short ourString; /* counter to index up to strIndex */
- char *resStr; /* string pointer to STR# string to replace */
- long oldSize; /* size of STR# resource before call */
- long newSize; /* size of STR# resource after call */
- unsigned long offset; /* resource offset to str to replace*/
-
- /* make sure index is in bounds */
-
- if (resID < 1)
- return -1;
-
- /* make sure resource exists */
-
- theRes = GetResource('STR#',resID);
- if (ResError()!=noErr)
- return ResError();
- if (!theRes || !(*theRes))
- return resNotFound;
-
- HLock(theRes);
- HNoPurge(theRes);
-
- /* get # of strings in STR# */
-
- BlockMove(*theRes,&numStrings,sizeof(short));
- if (strIndex > numStrings)
- return resNotFound;
-
- /* get a pointer to the string to replace */
-
- offset = sizeof(short);
- resStr = (char *) *theRes + sizeof(short);
- for (ourString=1; ourString<strIndex; ourString++) {
- offset += 1+resStr[0];
- resStr += 1+resStr[0];
- }
-
- /* grow/shrink resource handle to make room for new string */
-
- oldSize = GetHandleSize(theRes);
- newSize = oldSize - resStr[0] + theStr[0];
- HUnlock(theRes);
- SetHandleSize(theRes,newSize);
- if (MemError()!=noErr) {
- ReleaseResource(theRes);
- return -1;
- }
- HLock(theRes);
- resStr = *theRes + offset;
-
- /* move old data forward/backward to make room */
-
- BlockMove(resStr+resStr[0]+1, resStr+theStr[0]+1, oldSize-offset-resStr[0]-1
-
- /* move new data in */
-
- BlockMove(theStr,resStr,theStr[0]+1);
-
- /* write resource out */
-
- ChangedResource(theRes);
- WriteResource(theRes);
- HPurge(theRes);
- ReleaseResource(theRes);
-
- return ResError();
- }
-
- ----------
-
-